﻿using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.IO;
using System.Diagnostics;
using System;
namespace GenerationCode
{
    public partial class frmFormMain : Form
    {
        private string defaultCoder = "Nguyen Van Ty";
        private bool defaultWriteFile = true;
        private string selectAllTable = "--- All ---";
        public frmFormMain()
        {
            InitializeComponent();
           // GetServerDb();
            this.txtName.Text = defaultCoder;
            this.chkWrite.Checked = defaultWriteFile;
            //txtFolder.Text="F:\\NGUYENVANTY\\Project\\Chondat_NVA\\IV. ToolGencode\\Gencode";

        }

        #region Event
        private void btnConnect_Click(object sender, System.EventArgs e)
        {
            if (cboServerName.Text.ToString() == "---")
            {
                MessageBox.Show(this, "Please choice a server.", "Error");
                cboServerName.Focus();
                return;
            }
            try
            {

                Cursor.Current = Cursors.WaitCursor;
                Utils.Server server = new GenerationCode.Utils.Server(
                    this.cboServerName.Text.ToString(),
                    this.txtUserName.Text, this.txtPassword.Text);
                IList lst = server.Databases;
                this.cboDatabaseName.Items.Clear();
                foreach (Utils.Database db in lst)
                {
                    this.cboDatabaseName.Items.Add(db);
                    this.cboDatabaseName.DisplayMember = "Name";
                }
                Cursor.Current = Cursors.Arrow;
                this.cboDatabaseName.Enabled = true;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
            Cursor.Current = Cursors.Arrow;
        }
        /// <summary>
        /// Gen code for one table
        /// </summary>
        /// <param name="tableName"></param>
        private void GenTable(Utils.Table table, bool viewResult, DirectoryInfo dirSql, DirectoryInfo dirdataacess, DirectoryInfo dirProc)
        {
            table.GetColumns();
            DirectoryInfo dir = Directory.CreateDirectory(txtFolder.Text + "\\" + this.txtProject.Text.Trim() + "\\Object\\" + table.Name);
            //check if table has any key		
            if (table.KeyList.Count == 0)
            {
                DialogResult result = MessageBox.Show(this,
                        "This table " + table.Name + " has not a key yet! Do you want to add key(s)!",
                        "Error", MessageBoxButtons.YesNo);
                if (result == DialogResult.Yes)
                {
                  
                    frmInputKey formKey = new frmInputKey(table.Columns);
                    DialogResult r = formKey.ShowDialog(this);
                    if (r.Equals(DialogResult.OK))
                    {
                        string keyString = string.Empty;
                        if (formKey.lstKey.Count > 0)
                        {
                            foreach (string key in formKey.lstKey)
                            {
                                keyString += " " + key + ",";
                            }
                            keyString = keyString.Remove(keyString.Length - 1, 1);
                            if (formKey.isSetPrimaryKey)
                            {
                                Utils.Utility.SetKeyForTable(table.ConnectionString, table.Name, keyString);
                                table.GetColumns();
                            }
                            else
                            {
                                table.KeyList = formKey.lstKey;                                
                            }
                        }
                        else
                        {
                            MessageBox.Show("A certain error happened. Please try again!");
                            return;
                        }
                    }
                    else
                        return;
                }
                else
                    return;
            }

            bool genFunctionToControl = false;

            string valueField = string.Empty;
            string displayField = string.Empty;
            if (chkGenToControl.Checked)
            {
                genFunctionToControl = true;
                valueField = cmbValueField.Text;
                displayField = cmbDisplayField.Text;
            }
            //table object
            CSClasses.TableObject tableoject = new GenerationCode.CSClasses.TableObject(table, this.txtProject.Text, this.txtName.Text, this.txtEmail.Text);
            if (viewResult)
                this.txtObject.Text = tableoject.ObjectClass;
            string fileName = string.Empty;
            if (this.chkWrite.Checked)
            {
                fileName = dir.FullName + "\\" + table.Name + ".cs";
                this.FillToFile(fileName, tableoject.ObjectClass);
                CSClasses.TableObjectResult tableresult = new GenerationCode.CSClasses.TableObjectResult(table, this.txtProject.Text, this.txtName.Text, this.txtEmail.Text);
                fileName = dir.FullName + "\\" + table.Name + "Result.cs";
                this.FillToFile(fileName, tableresult.ObjectClass);
                //gen condition
               // CSClasses.TableCondition tableCondition = new GenerationCode.CSClasses.TableCondition(table, this.txtProject.Text, this.txtName.Text, this.txtEmail.Text);
               // fileName = dir.FullName + "\\" + table.Name + "Condition.cs";
               // this.FillToFile(fileName, tableCondition.ObjectClass);
            }

            //gen object to control
            if (genFunctionToControl)
            {
                CSClasses.TableObjectToControl tableTocontrol = new GenerationCode.CSClasses.TableObjectToControl(table, this.txtProject.Text, this.txtName.Text, this.txtEmail.Text, valueField, displayField);
                if (chkWrite.Checked)
                {
                    fileName = dir.FullName + "\\" + table.Name + "ToControl.cs";
                    this.FillToFile(fileName, tableTocontrol.ObjectClass);
                }
                if (viewResult)
                    txtToControlResult.Text = tableTocontrol.ObjectClass;
                //gen to control condition 
                CSClasses.ToControlCondition toControlCondition = new GenerationCode.CSClasses.ToControlCondition(table, this.txtProject.Text, this.txtName.Text, this.txtEmail.Text);
                if (viewResult)
                    txtToControlCondition.Text = toControlCondition.ObjectClass;
                fileName = dir.FullName + "\\" + table.Name + "ToControlCondition.cs";
                this.FillToFile(fileName, toControlCondition.ObjectClass);

            }
            else
            {
                txtToControlCondition.Text = string.Empty;
                txtToControlResult.Text = string.Empty;
            }

            //CSClasses.AccessProjectDetail accessdetail = new GenerationCode.CSClasses.AccessProjectDetail(table, txtProject.Text, txtName.Text, txtEmail.Text, valueField, displayField);
            CSClasses.BaseDataAccess baseDataAccess = new GenerationCode.CSClasses.BaseDataAccess(table, txtProject.Text, txtName.Text, txtEmail.Text, valueField, displayField);
            CSClasses.ExtendDataAccess extendDataAccess = new GenerationCode.CSClasses.ExtendDataAccess(table, txtProject.Text, txtName.Text, txtEmail.Text);


            if (this.chkWrite.Checked)
            {
                fileName = dirdataacess.FullName + "\\" + table.Name + "DaoBase.cs";
                this.FillToFile(fileName, baseDataAccess.ObjectClass);
                //gen dataAccess Class
                fileName = dirdataacess.FullName + "\\" + table.Name + "Dao.cs";
                this.FillToFile(fileName, extendDataAccess.ObjectClass);
            }
            if (viewResult)
                txtDataAccess.Text = baseDataAccess.ObjectClass;
            CSClasses.ObjectUtil objutil = new GenerationCode.CSClasses.ObjectUtil(table, txtProject.Text, txtName.Text, txtEmail.Text, genFunctionToControl);
            if (viewResult)
                this.txtUtil.Text = objutil.GetObject();
            if (this.chkWrite.Checked)
            {
                fileName = dirSql.FullName + "\\" + table.Name + "Util.cs";
                this.FillToFile(fileName, objutil.GetObject());

            }
            CSClasses.PROCEDURE procedure = new GenerationCode.CSClasses.PROCEDURE(table, txtProject.Text, txtName.Text, txtEmail.Text, valueField, displayField);
            if (viewResult)
                txtStoreProcedure.Text = procedure.ObjectClass;
            if (this.chkWrite.Checked)
            {
                fileName = dirProc.FullName + "\\" + table.Name + "Procedure.sql";
                this.FillToFile(fileName, procedure.ObjectClass);
            }
        }

      /*  private void GenTable(Utils.Table table, bool viewResult, DirectoryInfo dirSql, DirectoryInfo dirdataacess, DirectoryInfo dirProc)
        {
            table.GetColumns();
            DirectoryInfo dir = Directory.CreateDirectory(txtFolder.Text + "\\" + this.txtProject.Text.Trim() + "\\Object\\" + table.Name);
            //check if table has any key		
            if (table.KeyList.Count == 0)
            {
                DialogResult result = MessageBox.Show(this,
                        "This table " + table.Name + " has not a key yet! Do you want to add key(s)!",
                        "Error", MessageBoxButtons.YesNo);
                if (result == DialogResult.Yes)
                {

                    frmInputKey formKey = new frmInputKey(table.Columns);
                    DialogResult r = formKey.ShowDialog(this);
                    if (r.Equals(DialogResult.OK))
                    {
                        string keyString = string.Empty;
                        if (formKey.lstKey.Count > 0)
                        {
                            foreach (string key in formKey.lstKey)
                            {
                                keyString += " " + key + ",";
                            }
                            keyString = keyString.Remove(keyString.Length - 1, 1);
                            if (formKey.isSetPrimaryKey)
                            {
                                Utils.Utility.SetKeyForTable(table.ConnectionString, table.Name, keyString);
                                table.GetColumns();
                            }
                            else
                            {
                                table.KeyList = formKey.lstKey;
                            }
                        }
                        else
                        {
                            MessageBox.Show("A certain error happened. Please try again!");
                            return;
                        }
                    }
                    else
                        return;
                }
                else
                    return;
            }

            bool genFunctionToControl = false;

            string valueField = string.Empty;
            string displayField = string.Empty;
            if (chkGenToControl.Checked)
            {
                genFunctionToControl = true;
                valueField = cmbValueField.Text;
                displayField = cmbDisplayField.Text;
            }
            //table object
            CSClasses.TableObject tableoject = new GenerationCode.CSClasses.TableObject(table, this.txtProject.Text, this.txtName.Text, this.txtEmail.Text);
            if (viewResult)
                this.txtObject.Text = tableoject.ObjectClass;
            string fileName = string.Empty;
            if (this.chkWrite.Checked)
            {
                fileName = dir.FullName + "\\" + table.Name + ".cs";
                this.FillToFile(fileName, tableoject.ObjectClass);
                CSClasses.TableObjectResult tableresult = new GenerationCode.CSClasses.TableObjectResult(table, this.txtProject.Text, this.txtName.Text, this.txtEmail.Text);
                fileName = dir.FullName + "\\" + table.Name + "Result.cs";
                this.FillToFile(fileName, tableresult.ObjectClass);
                //gen condition
                CSClasses.TableCondition tableCondition = new GenerationCode.CSClasses.TableCondition(table, this.txtProject.Text, this.txtName.Text, this.txtEmail.Text);
                fileName = dir.FullName + "\\" + table.Name + "Condition.cs";
                this.FillToFile(fileName, tableCondition.ObjectClass);
            }

            //gen object to control
            if (genFunctionToControl)
            {
                CSClasses.TableObjectToControl tableTocontrol = new GenerationCode.CSClasses.TableObjectToControl(table, this.txtProject.Text, this.txtName.Text, this.txtEmail.Text, valueField, displayField);
                if (chkWrite.Checked)
                {
                    fileName = dir.FullName + "\\" + table.Name + "ToControl.cs";
                    this.FillToFile(fileName, tableTocontrol.ObjectClass);
                }
                if (viewResult)
                    txtToControlResult.Text = tableTocontrol.ObjectClass;
                //gen to control condition 
                CSClasses.ToControlCondition toControlCondition = new GenerationCode.CSClasses.ToControlCondition(table, this.txtProject.Text, this.txtName.Text, this.txtEmail.Text);
                if (viewResult)
                    txtToControlCondition.Text = toControlCondition.ObjectClass;
                fileName = dir.FullName + "\\" + table.Name + "ToControlCondition.cs";
                this.FillToFile(fileName, toControlCondition.ObjectClass);

            }
            else
            {
                txtToControlCondition.Text = string.Empty;
                txtToControlResult.Text = string.Empty;
            }

            //CSClasses.AccessProjectDetail accessdetail = new GenerationCode.CSClasses.AccessProjectDetail(table, txtProject.Text, txtName.Text, txtEmail.Text, valueField, displayField);
            CSClasses.BaseDataAccess baseDataAccess = new GenerationCode.CSClasses.BaseDataAccess(table, txtProject.Text, txtName.Text, txtEmail.Text, valueField, displayField);
            CSClasses.ExtendDataAccess extendDataAccess = new GenerationCode.CSClasses.ExtendDataAccess(table, txtProject.Text, txtName.Text, txtEmail.Text);


            if (this.chkWrite.Checked)
            {
                fileName = dirdataacess.FullName + "\\" + table.Name + "DaoBase.cs";
                this.FillToFile(fileName, baseDataAccess.ObjectClass);
                //gen dataAccess Class
                fileName = dirdataacess.FullName + "\\" + table.Name + "Dao.cs";
                this.FillToFile(fileName, extendDataAccess.ObjectClass);
            }
            if (viewResult)
                txtDataAccess.Text = baseDataAccess.ObjectClass;
            CSClasses.ObjectUtil objutil = new GenerationCode.CSClasses.ObjectUtil(table, txtProject.Text, txtName.Text, txtEmail.Text, genFunctionToControl);
            if (viewResult)
                this.txtUtil.Text = objutil.GetObject();
            if (this.chkWrite.Checked)
            {
                fileName = dirSql.FullName + "\\" + table.Name + "Util.cs";
                this.FillToFile(fileName, objutil.GetObject());

            }
            CSClasses.PROCEDURE procedure = new GenerationCode.CSClasses.PROCEDURE(table, txtProject.Text, txtName.Text, txtEmail.Text, valueField, displayField);
            if (viewResult)
                txtStoreProcedure.Text = procedure.ObjectClass;
            if (this.chkWrite.Checked)
            {
                fileName = dirProc.FullName + "\\" + table.Name + "Procedure.sql";
                this.FillToFile(fileName, procedure.ObjectClass);
            }
        }*/
        private void btbGenerate_Click(object sender, System.EventArgs e)
        {


            DirectoryInfo dirSql = null;
            DirectoryInfo dirdataacess = null;
            DirectoryInfo dirProc = null;
            //check errors
            if (this.txtProject.Text == string.Empty)
            {
                MessageBox.Show("Please enter Project Name!", "Error");
                return;
            }
            if (this.chkWrite.Checked)
            {
                if (this.txtFolder.Text == string.Empty)
                {
                    MessageBox.Show("Please enter the path!", "Error");
                    return;
                }

                dirSql = Directory.CreateDirectory(txtFolder.Text + "\\" + this.txtProject.Text.Trim() + "\\Business");
                dirdataacess = Directory.CreateDirectory(txtFolder.Text + "\\" + this.txtProject.Text + "\\DataAccess");
                dirProc = Directory.CreateDirectory(txtFolder.Text + "\\" + this.txtProject.Text + "\\Procedure");
            }
            this.Cursor = Cursors.WaitCursor;
            if (cboTableName.Text != this.selectAllTable)
            {
                Utils.Table tbl = (Utils.Table)cboTableName.SelectedItem;
                //check cache data
                DialogResult resultCache = MessageBox.Show(this, "Do you want cache data for this table?", "Confirm", MessageBoxButtons.YesNo);
                if (resultCache == DialogResult.Yes)
                    tbl.IsCacheData = true;
                else
                    tbl.IsCacheData = false;
                //check multilanguage data
                DialogResult resultMulitlanguage = MessageBox.Show(this, "Do you want gen multilanguage for this table?", "Confirm", MessageBoxButtons.YesNo);
                if (resultMulitlanguage == DialogResult.Yes)
                    tbl.IsMultilanguage = true;
                else
                    tbl.IsMultilanguage = false;
                GenTable(tbl, true, dirSql, dirdataacess, dirProc);
            }
            else
            {
                List<Utils.Table> lstTable = new List<GenerationCode.Utils.Table>();
                for (int i = 1; i < cboTableName.Items.Count; i++)
                {
                    Utils.Table tbl = (Utils.Table)cboTableName.Items[i];
                    lstTable.Add(tbl);                   
                }
                frmSetCacheDataTable frmSetCacheDataTable = new frmSetCacheDataTable(lstTable);
                DialogResult r = frmSetCacheDataTable.ShowDialog(this);
                for (int i = 0; i < frmSetCacheDataTable.lstTable.Count; i++)
                {
                   if(lstTable[i].IsSelect)
                       GenTable(frmSetCacheDataTable.lstTable[i], false, dirSql, dirdataacess, dirProc);
                }
                

            }
            this.Cursor = Cursors.Arrow;
            MessageBox.Show("Process is completed");
        }

        private void FillTabField(string fileName, string p)
        {
            throw new NotImplementedException();
        }

        private void btnRefresh_Click(object sender, System.EventArgs e)
        {
            Cursor.Current = Cursors.WaitCursor;
            cboServerName.SelectedIndexChanged -= new EventHandler(cboServerName_SelectedIndexChanged);
            cboServerName.SelectedIndex = 0;
            cboServerName.SelectedIndexChanged += new EventHandler(cboServerName_SelectedIndexChanged);
            this.cboDatabaseName.Items.Clear();
            this.cboTableName.Items.Clear();
            this.cboDatabaseName.Enabled = false;
            this.cboTableName.Enabled = false;
            this.btbGenerate.Enabled = false;
            txtUserName.Text = string.Empty;
            txtPassword.Text = string.Empty;
            chkGenToControl.Checked = false;
            chkGenToControl.Enabled = false;
            txtProject.Text = string.Empty;
            txtFolder.Text = string.Empty;
            txtEmail.Text = string.Empty;
            lstFields.Items.Clear();
            txtDataAccess.Text = string.Empty;
            txtUtil.Text = string.Empty;
            txtObject.Text = string.Empty;
            txtStoreProcedure.Text = string.Empty;
            txtToControlCondition.Text = string.Empty;
            txtToControlResult.Text = string.Empty;
            this.txtName.Text = defaultCoder;
            this.chkWrite.Checked = defaultWriteFile;
            this.chkWrite.Enabled = true;
            tabControl1.Visible = true;
        }
        private void btnExit_Click(object sender, System.EventArgs e)
        {
            this.Dispose();
        }
        private void btnBrowser_Click(object sender, System.EventArgs e)
        {
            if (this.fbdFolder.ShowDialog() == DialogResult.OK)
                this.txtFolder.Text = fbdFolder.SelectedPath;
        }
        private void cboServerName_SelectedIndexChanged(object sender, EventArgs e)
        {
            //if (cboServerName.Text.ToString() != "---")
            //{
            //    btnConnect.Enabled = true;
            //}
            //else
            //    btnConnect.Enabled = false;
            chkGenToControl.Enabled = false;
            chkGenToControl.Checked = false;
        }

        private void mniDomainSearch_Click(object sender, System.EventArgs e)
        {
            if (txtFolder.Text.Trim() == string.Empty)
            {
                MessageBox.Show(this, "Please choose folder.", "Error!");
                this.btnBrowser.Focus();
                return;
            }
            if (txtProject.Text.Trim() == string.Empty)
            {
                MessageBox.Show(this, "Please input project.", "Error!");
                this.txtProject.Focus();
                return;
            }
            //      frmDomainSearch frm = new frmDomainSearch(this.txtProject.Text,this.txtFolder.Text,
            //        this.txtName.Text, this.txtEmail.Text);
            //      frm.ShowDialog();    
        }
        private void cboDatabaseName_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                Cursor.Current = Cursors.WaitCursor;
                cboTableName.SelectedIndexChanged -= new EventHandler(cboTableName_SelectedIndexChanged);
                cboTableName.Items.Clear();
                Utils.Database db = (Utils.Database)this.cboDatabaseName.SelectedItem;
                IList lst = db.Tables;
                foreach (Utils.Table tb in lst)
                {
                  //  if (!tb.Name.Contains(Utils.Utility.MultilanguageTableName))
                  //  {
                        this.cboTableName.Items.Add(tb);
                   // }
                     
                    
                }
                this.cboTableName.DisplayMember = "Name";
                cboTableName.Items.Insert(0, this.selectAllTable);
                cboTableName.SelectedIndexChanged += new EventHandler(cboTableName_SelectedIndexChanged);
                chkGenToControl.Enabled = false;
                chkGenToControl.Checked = false;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
            this.cboTableName.Enabled = true;
            this.btnRefresh.Enabled = true;
            Cursor.Current = Cursors.Arrow;
        }
        private void cboTableName_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cboTableName.Text != this.selectAllTable)
            {
                chkWrite.Enabled = true;
                tabControl1.Visible = true;
                this.lstFields.Items.Clear();
                this.txtDataAccess.Text = string.Empty;
                this.txtObject.Text = string.Empty;
                this.txtUtil.Text = string.Empty;
                Utils.Table table = (Utils.Table)this.cboTableName.SelectedItem;
                IList lstCol = table.GetColumns();
                this.FillTabField(lstCol);
                //

                GetFieldToCombobox(cmbDisplayField, lstCol);
                GetFieldToCombobox(cmbValueField, lstCol);
                if (cmbDisplayField.Items.Count > 0)
                    chkGenToControl.Enabled = true;
                else
                    chkGenToControl.Enabled = false;
            }
            else
            {
                chkGenToControl.Enabled = false;
                chkGenToControl.Checked = false;
                tabControl1.Visible = false;
                chkWrite.Checked = true;
                chkWrite.Enabled = false;
            }
            this.btbGenerate.Enabled = true;
        }
        private void chkGenToControl_CheckedChanged(object sender, EventArgs e)
        {
            if (chkGenToControl.Checked)
            {
                cmbValueField.Visible = true;
                cmbDisplayField.Visible = true;
                lblDisplayField.Visible = true;
                lblValueField.Visible = true;
            }
            else
            {
                cmbValueField.Visible = false;
                cmbDisplayField.Visible = false;
                lblDisplayField.Visible = false;
                lblValueField.Visible = false;
            }
        }
        #endregion Event

        #region Methods
        private void GetServerDb()
        {
            cboServerName.Items.Clear();
            cboServerName.Items.Add("---");
            SQLDMO.NameList sqlList = null;
            SQLDMO.Application sqlApp = null;
            try
            {
                sqlApp = new SQLDMO.Application();
                sqlList = sqlApp.ListAvailableSQLServers();
                for (int ctr = 1; ctr <= sqlList.Count; ctr++)
                    cboServerName.Items.Add(sqlList.Item(ctr));

            }
            catch (Exception ex)
            {
            }
            finally
            {
                if (sqlList != null)
                    sqlList = null;
                if (sqlApp != null)
                    sqlApp = null;
            }
            cboServerName.SelectedIndex = 0;
        }

        private void FillTabField(IList lst)
        {
            string text = string.Empty;
            foreach (Utils.Column col in lst)
            {
                if (col.SqlType == "text" || col.SqlType == "ntext" || col.SqlType == "image")
                    text = col.Name + "              " + col.SqlType;
                else
                    text = col.Name + "              " + col.SqlType + "              " + col.Length;
                this.lstFields.Items.Add(text);
            }
        }
        private void GetFieldToCombobox(ComboBox cmb, IList lst)
        {
            cmb.Items.Clear();
            foreach (Utils.Column col in lst)
            {
                cmb.Items.Add(col.Name);
            }
            cmb.SelectedIndex = 0;
        }
        private void FillToFile(string fileName, string data)
        {
            FileInfo file = new FileInfo(fileName);
            StreamWriter text = null;
            if (chkWrite.Checked == true)
            {
                text = file.CreateText();
                text.Write(data);
                text.Flush();
                text.Close();
            }
        }
        #endregion Methods

        private void btnGenObject_Click(object sender, EventArgs e)
        {

        }





    }
}
